package com.csaba.connector.otp;

import java.io.StringReader;
import java.util.logging.Logger;

import org.apache.commons.httpclient.NameValuePair;

import com.csaba.connector.ServiceException;
import com.csaba.connector.model.Account;
import com.csaba.connector.model.Session;
import com.csaba.connector.otp.model.OTPBank;
import com.csaba.connector.otp.model.OTPRequestFactory;
import com.csaba.connector.otp.model.OTPSession;
import com.csaba.connector.otp.parser.AccountBalanceParser;
import com.csaba.connector.otp.parser.OTPCodes;
import com.csaba.connector.service.AbstractAccountService;
import com.csaba.util.LoggerHelper;

public class OTPAccountService extends AbstractAccountService
{
	private final static Logger logger = LoggerHelper.getDefaultLogger();

	@Override
	public void execute( final Session session ) throws ServiceException
	{
		if ( !( session instanceof OTPSession ) )
			throw new ServiceException("Unsupported session for OTP services: " + session.getClass().getName());

		final OTPSession otp = (OTPSession) session;

		String accountListRequest = null;
		if ( otp.isRemotePropertySet(OTPCodes.CACHE_ACCOUNT_LIST_REQUEST) )
		{
			accountListRequest = (String) otp.removeRemoteProperty(OTPCodes.CACHE_ACCOUNT_LIST_REQUEST);
		}
		else
		{
			accountListRequest = otp.doGet(OTPRequestFactory.HOMEBANK_REQUEST_URL_BASE
					+ OTPRequestFactory.REQUEST_GET_ACCOUNT_LIST + "?muveletStatusz=vegrehajtas");
			otp.debugFile("accountListRequest", accountListRequest);
		}

		String result = null;
		//parse poll instruction
		final String pollUrl = TransactionPolling.parsePollTransaction(accountListRequest);
		if ( pollUrl != null )
		{
			logger.fine("Poll transaction URL: " + pollUrl);

			if ( !( new TransactionPolling(otp, pollUrl) ).poll() )
				throw new ServiceException("Error getting account list within the time limit.");

			//get the result, after poll
			final NameValuePair[] data = new NameValuePair[] {
					new NameValuePair("kliensTranzakcioId", String.valueOf(otp.getOperationCounter())),
					new NameValuePair("muveletStatusz", "varakozas"), };

			result = otp.doPost(OTPRequestFactory.HOMEBANK_REQUEST_URL_BASE + OTPRequestFactory.REQUEST_GET_ACCOUNT_LIST,
					data);
			otp.debugFile("accountListReply", result);
		}
		else
		{ //the account list may be already returned.
			result = accountListRequest;
		}

		//parse account result
		if ( AccountBalanceParser.isParsable(result) )
		{
			try
			{
				accounts = AccountBalanceParser.parseAccountList(new StringReader(result)); //FIXME use stream as a result of get/put
				for ( final Account account : accounts )
				{ //fix parameters of accounts
					account.setBank(OTPBank.getInstance());
					account.setCustomer(session.getCustomer());

					//TODO try to get the minimum necessary information from the interface
					account.setIBAN("<unknown>");
					account.setType("<unknown>");
				}
			}
			catch ( final Exception e )
			{
				throw new ServiceException("Error during processing account balances.", e);
			}
		}
		else
		{
			throw new ServiceException("Unable to download a valid account list.");
		}
	}
}
